/*
 * \brief  Virtual PCI bus for DDE kit
 * \author Christian Helmuth
 * \date   2008-10-22
 *
 * Design notes:
 *
 * - Provide a virtual PCI bus in pcibus.cc
 *   - Grab all accessible devices at pci_drv and populate virtual bus. (This
 *     also works if parents/device managers limit device access in the
 *     future.)
 *   - Provide config space access and _temporarily_ limit write access to
 *     safe device-specific registers. (iIn the future, the PCI driver must
 *     enforce capability-based access permissions.)
 */

/*
 * Copyright (C) 2008-2009 Christian Helmuth
 * Genode Labs, Feske & Helmuth Systementwicklung GbR
 *
 * This file is part of the Genode OS framework, which is distributed
 * under the terms of the GNU General Public License version 2.
 */

#include "pci_bus.h"

using namespace Dde_kit;


/****************
 ** PCI device **
 ****************/

uint32_t Pci_device::config_read(unsigned char address, Pci::Device::Access_size size)
{
	uint32_t result = _device.config_read(address, size);

//	PDBG("PCI read cfg (%d) %x of 00:%02x.%x -- %x",
//	     size, address, _devfn >> 3, _devfn & 0x07, result);

	return result;
}


void Pci_device::config_write(unsigned char address, uint32_t val,
                              Pci::Device::Access_size size)
{
	_device.config_write(address, val, size);

//	PDBG("PCI write cfg (%d) %x (%x) of 00:%02x.%x",
//	     size, address, val, _devfn >> 2, _devfn & 0x07);
}


/*************
 ** PCI bus **
 *************/

Pci_bus::Pci_bus() : _current_dev_num(0)
{
	/*
	 * Iterate through all accessible devices and populate virtual
	 * PCI bus.
	 */
	Pci::Device_capability prev_device_cap,
	                            device_cap = _pci_drv.first_device();

	while (device_cap.valid()) {

		Pci_device *device = new (env()->heap())
		                     Pci_device(_current_dev_num++ << 3, device_cap);

		_devices.insert(device);

		prev_device_cap = device_cap;
		device_cap = _pci_drv.next_device(prev_device_cap);
	}
}
